﻿/* 
 * This file is part of marvellous-components project.
 * 
 * The marvellous-components is free software: you can redistribute it 
 * and/or modify it under the terms of the GNU General Public License 
 * version 3 as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Drawing;

namespace marvellous_components.LuxuriousMonthCalendar
{

    public class LuxuriousMonthCalendar : DataGridView
    {
        private const int COLS = 7;

        private const int ROWS = 6;

        private DayOfWeek firstDayOfWeek = DayOfWeek.Monday;

        private Color colorWeekend = Color.LightGray;

        private Color colorFutureCells = Color.LightGray;

        private Color colorCurrentCells = Color.White;

        private DataGridViewTextBoxColumn[] columns = new System.Windows.Forms.DataGridViewTextBoxColumn[COLS];


        public void InitCalendar() {
            InitCalendar(null);
        }

        /// <summary>
        /// Method must be invoked in order to prepare columns and initialize data.
        /// </summary>
        public void InitCalendar(DataGridViewCellEventHandler cellClickHandler)
        {
            DataGridViewCellStyle columnDateStyle = new DataGridViewCellStyle();
            columnDateStyle.Format = "dd";

            for (int col = 0; col < COLS; col++)
            {
                columns[col] = new DataGridViewTextBoxColumn();
                columns[col].ReadOnly = true;
                columns[col].Resizable = DataGridViewTriState.False;
                columns[col].DefaultCellStyle = columnDateStyle;
            }

            this.AllowUserToAddRows = false;
            this.AllowUserToDeleteRows = false;
            this.AllowUserToResizeColumns = false;
            this.AllowUserToResizeRows = false;
            this.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
            this.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.None;
            this.ColumnHeadersVisible = false;
            this.RowHeadersVisible = false;
            this.ScrollBars = System.Windows.Forms.ScrollBars.None;
            this.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect;
            this.MultiSelect = false;
            this.Columns.AddRange(columns);
            this.Rows.Add(ROWS);

            this.SelectionChanged += new System.EventHandler(this.this_SelectionChanged);
            this.Resize += new System.EventHandler(this.this_Resize);
            if (cellClickHandler != null)
            {
                this.CellClick += cellClickHandler;
            }

            DateTime now = DateTime.Now;
            DateTime today = new DateTime(now.Year, now.Month, now.Day);

            DateTime dt = today.AddDays(-COLS * ROWS + 1);
            while (!dt.DayOfWeek.Equals(firstDayOfWeek))
            {
                dt = dt.AddDays(1);
            }

            for (int row = 0; row < ROWS; row++)
            {
                for (int col = 0; col < COLS; col++)
                {
                    DataGridViewCell cell = this.Rows[row].Cells[col];
                    cell.Value = dt;
                    cell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
                    dt = dt.AddDays(1);
                }
            }
            updateHeight();
            updateColours(new List<HighlightedDate>());
        }

        public DateTime getDate(int row, int col)
        {
            return (DateTime)this.Rows[row].Cells[col].Value;
        }

        public void updateColours(List<HighlightedDate> dates)
        {
            DateTime now = DateTime.Now;
            DateTime today = new DateTime(now.Year, now.Month, now.Day);

            for (int row = 0; row < ROWS; row++)
            {
                for (int col = 0; col < COLS; col++)
                {
                    DataGridViewCell cell = this.Rows[row].Cells[col];
                    DateTime dt = (DateTime)cell.Value;

                    // setting background
                    if (dt.CompareTo(today) > 0)
                    {
                        cell.Style.BackColor = colorFutureCells;
                    }
                    else
                    {
                        cell.Style.BackColor = colorCurrentCells;
                    }

                    // setting default colours;
                    if (DayOfWeek.Sunday.Equals(dt.DayOfWeek))
                    {
                        cell.Style.ForeColor = Color.Red;
                        cell.Style.BackColor = colorWeekend;
                    }
                    else if (DayOfWeek.Saturday.Equals(dt.DayOfWeek))
                    {
                        cell.Style.BackColor = colorWeekend;
                    }
                    else
                    {
                        cell.Style.ForeColor = Color.FromKnownColor(KnownColor.WindowText);
                    }
                    
                    foreach (HighlightedDate hl in dates)
                    {
                        if (dt.Equals(hl.Date))
                        {
                            cell.Style.BackColor = hl.Colour;
                        }
                    }
                }
            }
        }

        private void updateHeight()
        {
            int rowHeight = (this.Height - 1 )/ ROWS;
            for (int row = 0; row < (this.Rows.Count); row++)
            {
                this.Rows[row].Height = rowHeight;
            }
            this.Rows[this.Rows.Count - 1].Height += this.Height - ROWS * rowHeight - 3;
        }

        private void this_SelectionChanged(object sender, EventArgs e)
        {
            this.ClearSelection();
        }


        private void this_Resize(object sender, EventArgs e)
        {
            this.updateHeight();
        }

    }

}
